package mwa.cs.ar.ctrl;

import java.io.IOException;
import java.io.PrintWriter;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import mwa.cs.dao.ArDAO;
import mwa.cs.dao.CustHHDAO;
import mwa.cs.dao.CustMonthlyDAO;
import mwa.cs.dao.SMErrorLogDAO;
import mwa.cs.database.Database;
import mwa.cs.hh.biz.MeterFunction;
import mwa.cs.model.Ar;
import mwa.cs.model.CustHH;
import mwa.cs.util.JDate;

import org.json.simple.JSONArray;
import org.json.simple.JSONObject;

/**
 * Servlet implementation class CS42002Srvl
 */
public class CS42002Srvl extends HttpServlet {
	private static final long serialVersionUID = 1L;
	private int vnSiteId;
	private int vnUserId;
	private String vaUrlAddress;
	private String vaAgentBrowser;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public CS42002Srvl() {
        super();
        // TODO Auto-generated constructor stub
    }

    @SuppressWarnings("unchecked")
   	public void processRequest(HttpServletRequest request,
   			HttpServletResponse response) throws ServletException, IOException {
    	
    	vnSiteId = Integer.parseInt(request.getSession().getAttribute("site_id").toString());
		vnUserId = Integer.parseInt(request.getSession().getAttribute("user_id").toString());
		vaUrlAddress = request.getParameter("url_address");
		vaAgentBrowser = request.getParameter("agent_browser");
    	request.setCharacterEncoding("UTF-8");
		response.setCharacterEncoding("UTF-8");
		response.setContentType("text/JSON");
		String vaProcessType = request.getParameter("methodType");
		if (vaProcessType.equals("getDataAR")){
			getDataAR(request, response);
		} else if (vaProcessType.equals("getVatRate")) {
			getVatRate(request, response);
		} else if (vaProcessType.equals("calConsumption")) {
			calConsumption(request, response);
		} else {
			saveData(request, response);
		}
    }
    
    @SuppressWarnings("unchecked")
	public void saveData(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		PrintWriter voOut = response.getWriter();
		JSONObject voObject = new JSONObject();
		Database db = new Database(); 
		Ar voAR = new Ar();
    	ArDAO voARDAO = new ArDAO(db);
    	CustHHDAO voCustHHDAO = new CustHHDAO(db);
    	vnSiteId = Integer.parseInt(request.getSession().getAttribute("site_id").toString());

		String vaAccount = request.getParameter("account");
		String vaPeriodMonth = voCustHHDAO.findMaxMonth(vnSiteId);
		String vaPeriodYear = voCustHHDAO.findMaxYear(vnSiteId);
		String vaConsumption = request.getParameter("consumption").replace(",", "").trim();
		String vaWaterCharge = request.getParameter("waterCharge").replace(",", "").trim();
		String vaWaterFee = request.getParameter("waterFee").replace(",", "").trim();
		String vaVatAmount = request.getParameter("vatAmount").replace(",", "").trim();
		String vaBillAmount = request.getParameter("billAmount").replace(",", "").trim();
		String vaCurrentReadDate = request.getParameter("currentReadDate");
		String vaCurrentReadNumber = request.getParameter("currentReadNumber").trim();
		String vaGarbageCharge = request.getParameter("garbageCharge").replace(",", "").trim();
		String vaWasteWaterCharge = request.getParameter("wasteWaterCharge").replace(",", "").trim();
		String vaOtherCharge = request.getParameter("otherCharge").replace(",", "").trim();
		String vaTotalAmount = request.getParameter("totalAmount").replace(",", "").trim();
		String vaArReason = request.getParameter("arReason").trim();
		int vnUpdateUserId = 1; //(Integer) request.getSession().getAttribute("user_id");
		String vaUpdateDate = JDate.getDate();
		String vaUpdateTime = JDate.getTime();
		// เช็คค่า ถ้าเป็นค่า ว่าง ให้เป็น 0
		if (vaGarbageCharge.equals("")) vaGarbageCharge = "0.00";
		double vnGarbageCharge = Double.parseDouble(vaGarbageCharge);
		if (vaWasteWaterCharge.equals("")) vaWasteWaterCharge = "0.00";
		double vnWasteWaterCharge = Double.parseDouble(vaWasteWaterCharge);
		if (vaOtherCharge.equals("")) vaOtherCharge = "0.00";
		double vnOtherCharge = Double.parseDouble(vaOtherCharge);
		
		// set value
		voAR.setVnConsumption(Integer.parseInt(vaConsumption));
		voAR.setVnWaterFee(Double.parseDouble(vaWaterFee));
		voAR.setVnWaterCharge(Double.parseDouble(vaWaterCharge));
		voAR.setVnVatAmount(Double.parseDouble(vaVatAmount));
		voAR.setVnBillAmount(Double.parseDouble(vaBillAmount));
		voAR.setVaCurrentReadDate(vaCurrentReadDate.substring(6, 10) + vaCurrentReadDate.substring(3, 5) + vaCurrentReadDate.substring(0, 2));
		voAR.setVnCurrentReadNumber(Integer.parseInt(vaCurrentReadNumber));
		voAR.setVnGarbageCharge(vnGarbageCharge);
		voAR.setVnWasteWaterCharge(vnWasteWaterCharge);
		voAR.setVnOtherCharge(vnOtherCharge);
		voAR.setVnTotalAmount(Double.parseDouble(vaTotalAmount));
		voAR.setVaReason(vaArReason);
		voAR.setVnUpdateUserId(vnUpdateUserId);
		voAR.setVaUpdateDate(vaUpdateDate);
		voAR.setVaUpdateTime(vaUpdateTime);
		
		try{
			db.beginTransaction();
			boolean vbResult = voARDAO.editNewAR(vnSiteId, vaAccount, vaPeriodMonth, vaPeriodYear, voAR);
			if (vbResult) {
				voObject.put("message", "success");
			} else {
				voObject.put("message", "fail");
			}
			db.commit();
		} catch (Exception e) {
			SMErrorLogDAO.getInstance().addLog(0, "CS42002", JDate.getDate(), JDate.getTime(),vnUserId, "CS42002Srvl", e.getMessage(),vaUrlAddress, vaAgentBrowser);
			db.rollback();
			voObject.put("message", "fail");
		}
		db.close();
		voOut.print(voObject.toJSONString());
	}
    
    @SuppressWarnings("unchecked")
	public void getDataAR(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		
		PrintWriter voOut = response.getWriter();
		JSONObject voObject = new JSONObject();
		Database db = new Database();
    	ArDAO voARDAO = new ArDAO(db);
    	CustHHDAO voCustHHDAO = new CustHHDAO(db);
    	vnSiteId = Integer.parseInt(request.getSession().getAttribute("site_id").toString());
		String vaAccount = request.getParameter("account");
		
		String vaPeriodMount = voCustHHDAO.findMaxMonth(vnSiteId);
		String vaPeriodYear = voCustHHDAO.findMaxYear(vnSiteId);
		JSONArray voAccount = new JSONArray();
		JSONArray voZoneName = new JSONArray();
		JSONArray voRvoOuteDescription = new JSONArray();
		JSONArray voSequence = new JSONArray();
		JSONArray voFullName = new JSONArray();
		JSONArray voCustomerClass = new JSONArray();
		JSONArray voCustomerClassId = new JSONArray();
		JSONArray voAddress = new JSONArray(); 
		JSONArray voAllowance = new JSONArray();
		JSONArray voPreviousReadDate = new JSONArray();
		JSONArray voCurrentReadDate = new JSONArray();
		JSONArray voPreviousReadNumber = new JSONArray();
		JSONArray voCurrentReadNumber = new JSONArray();
		JSONArray voReason = new JSONArray();
		JSONArray voConsumption = new JSONArray();
		JSONArray voWaterCharge = new JSONArray();
		JSONArray voWaterFee = new JSONArray();
		JSONArray voVatAmount = new JSONArray();
		JSONArray voBillAmount = new JSONArray();
		JSONArray voGarbageCharge = new JSONArray();
		JSONArray voWasteWaterCharge = new JSONArray();
		JSONArray voOtherCharge = new JSONArray();
		JSONArray voTotalAmount = new JSONArray();
		JSONArray voReceiveDate = new JSONArray();
		
		List<Map<String, Object>> voArrayList = null;
		Map<String, Object> voMapAr = new HashMap<String, Object>();
		Map<String, Object> voMapArCount = new HashMap<String, Object>();
		voArrayList = voARDAO.searchARForUpdate(vnSiteId, vaAccount, vaPeriodMount, vaPeriodYear);
		DecimalFormat formatter = new DecimalFormat("#,##0.00");
		if (voArrayList.size() == 0){
    		voObject.put("message", "resultNull");
    	} else if (voArrayList.size() == 1){
    		voObject.put("message", "arFirstNOSave");
    	} else {
    		voMapArCount = voARDAO.searchCountAR(vnSiteId, vaAccount, vaPeriodMount, vaPeriodYear);
    		String countStatus = ""+ voMapArCount.get("COUNT");
    		if (voArrayList.size() == Integer.parseInt(countStatus)) {
    			voObject.put("message", "ARcancel");
    		} else {
    			for (int i = 0; i < 1; i++){
    				voMapAr = voArrayList.get(i);
    				voReceiveDate.add(voMapAr.get("RECEIVE_DATE"));
    				if (voReceiveDate.get(i) != null && voReceiveDate.get(i) != "") {
    	    			voObject.put("message", "receiveDate");
    				} else {
        				voAccount.add(voMapAr.get("ACCOUNT"));
            			voZoneName.add(voMapAr.get("ZONE_NAME"));
            			voRvoOuteDescription.add(voMapAr.get("ROUTE_DESCRIPTION"));
            			voSequence.add(voMapAr.get("SEQ"));
                		voFullName.add(voMapAr.get("FULL_NAME"));
                		voCustomerClass.add(voMapAr.get("DESCRIPTION"));
                		voCustomerClassId.add(voMapAr.get("CUSTOMER_CLASS"));
                		voAddress.add(voMapAr.get("ADDRESS"));
                		voAllowance.add(voMapAr.get("ALLOWANCE"));
                		voPreviousReadDate.add(voMapAr.get("PREVIOUS_READ_DATE"));
                		voCurrentReadDate.add(voMapAr.get("CURRENT_READ_DATE"));
                		voPreviousReadNumber.add(voMapAr.get("PREVIOUS_READ_NUMBER"));
                		voCurrentReadNumber.add(voMapAr.get("CURRENT_READ_NUMBER"));
                		voReason.add(voMapAr.get("REASON"));
                		voConsumption.add(voMapAr.get("CONSUMPTION"));
                		voWaterCharge.add(formatter.format(Double.parseDouble(voMapAr.get("WATER_CHARGE").toString())));
                		voWaterFee.add(formatter.format(Double.parseDouble(voMapAr.get("WATER_FEE").toString())));
                		voVatAmount.add(formatter.format(Double.parseDouble(voMapAr.get("VAT_AMOUNT").toString())));
                		voBillAmount.add(formatter.format(Double.parseDouble(voMapAr.get("BILL_AMOUNT").toString())));
                		voGarbageCharge.add(formatter.format(Double.parseDouble(voMapAr.get("GARBAGE_CHARGE").toString())));
                		voWasteWaterCharge.add(formatter.format(Double.parseDouble(voMapAr.get("WASTEWATER_CHARGE").toString())));
                		voOtherCharge.add(formatter.format(Double.parseDouble(voMapAr.get("OTHER_CHARGE").toString())));
                		voTotalAmount.add(formatter.format(Double.parseDouble(voMapAr.get("TOTAL_AMOUNT").toString())));
                		
                		voObject.put("account", voAccount);
                		voObject.put("zoneName", voZoneName);
                		voObject.put("rvoOuteDescription", voRvoOuteDescription);
                		voObject.put("sequence", voSequence);
                		voObject.put("fullName", voFullName);
                		voObject.put("customerClass", voCustomerClass);
                		voObject.put("customerClassId", voCustomerClassId);
                		voObject.put("address", voAddress);
                		voObject.put("allowance", voAllowance);
                		voObject.put("previousReadDate", voPreviousReadDate);
                		voObject.put("currentReadDate", voCurrentReadDate);
                		voObject.put("previousReadNumber", voPreviousReadNumber);
                		voObject.put("currentReadNumber", voCurrentReadNumber);
                		voObject.put("reason", voReason);
                		voObject.put("consumption", voConsumption);
                		voObject.put("waterCharge", voWaterCharge);
                		voObject.put("waterFee", voWaterFee);
                		voObject.put("vatAmount", voVatAmount);
                		voObject.put("billAmount", voBillAmount);
                		voObject.put("garbageCharge", voGarbageCharge);
                		voObject.put("wasteWaterCharge", voWasteWaterCharge);
                		voObject.put("otherCharge", voOtherCharge);
                		voObject.put("totalAmount", voTotalAmount);
    				}
        		}
    		}
    	}
    	db.close();
    	voOut.print(voObject.toJSONString());
	}
	
	@SuppressWarnings("unchecked")
	public void getVatRate(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {

		PrintWriter voOut = response.getWriter();
		JSONObject voObject = new JSONObject();
		vnSiteId = Integer.parseInt(request.getSession().getAttribute("site_id").toString());
		String vaWaterCharge = request.getParameter("waterCharge");
		String vaWaterFee = request.getParameter("waterFee");
		String vaCurrentDate = JDate.getDate();
		String vaVatAmountNew = MeterFunction.calVatRate(vnSiteId, vaCurrentDate, vaWaterCharge, vaWaterFee);
		voObject.put("vatAmountNew", vaVatAmountNew);
		voOut.print(voObject.toJSONString());
	}
	
	@SuppressWarnings("unchecked")
	public void calConsumption(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		
		PrintWriter voOut = response.getWriter();
		JSONObject voObject = new JSONObject();
		vnSiteId = Integer.parseInt(request.getSession().getAttribute("site_id").toString());

		double vnWaterChargeNew = 0.00;
		String vaDateAmount = "";
		String vaWaterChargeLast = "";
		String vaTypeAllowance = "";
		double vnDiscount = 0.00;
		DecimalFormat voFormatter = new DecimalFormat("#,##0.00");
		String vaAccount = request.getParameter("account");
		double vnConsumption = Double.parseDouble(request.getParameter("consumption"));
		String vaTypeCal = request.getParameter("typeCal");
		String vaCurrentReadDate = request.getParameter("currentReadDate");
		String vaPreviousReadDate = request.getParameter("previousReadDate");
		String vaCustomerClass = request.getParameter("customerClass");
		String vaAllowance = request.getParameter("allowance");
		String [] vaData = MeterFunction.getDiscountAllowance(vnSiteId);
		vaTypeAllowance = vaData[0];
		vnDiscount = Double.parseDouble(vaData[1]);
		// ประเภทของการคำนวณ
		if (vaTypeCal.equals("G")) { // คำนวณแบบปกติ
			// ส่วนลดทหารผ่านศึก
			if (vaAllowance.equals("1")) { 
				double percentConsumption = 0.00;
				if (vaTypeAllowance.equals("C")) { // กรณีลด % หน่วยน้ำที่ใช้
					percentConsumption = vnConsumption * vnDiscount;
					vnConsumption = vnConsumption - percentConsumption;
					vnWaterChargeNew = Double.parseDouble(MeterFunction.calNormalUsedUnitWater(vnSiteId, vaCustomerClass, vnConsumption).replace(",", ""));
				} else { // กรณีลด ค่าน้ำ
					vnWaterChargeNew = Double.parseDouble(MeterFunction.calNormalUsedUnitWater(vnSiteId, vaCustomerClass, vnConsumption).replace(",", "")) - vnDiscount;
				}
			} else { // ถ้าไม่มีส่วนลดทหารผ่านศึก
				vnWaterChargeNew = Double.parseDouble(MeterFunction.calNormalUsedUnitWater(vnSiteId, vaCustomerClass, vnConsumption).replace(",", ""));
			}
		} else { // คำนวณแบบเฉลี่ย
			try{
				double vnWaterUnit = 0.00;
				vaDateAmount = MeterFunction.CalDurationBetweenTwoDates(vaPreviousReadDate, vaCurrentReadDate);
				vaWaterChargeLast = MeterFunction.calculateAverageConsumption(vnSiteId, vaAccount);
				// ส่วนลดทหารผ่านศึก
				if (vaAllowance.equals("1")) {
					if (vaTypeAllowance.equals("C")) { // กรณีลด % หน่วยน้ำที่ใช้
						double vnPercentConsumption = 0.00;
						vnWaterUnit = Double.parseDouble(vaDateAmount) * Double.parseDouble(vaWaterChargeLast);
						vnPercentConsumption = vnWaterUnit * vnDiscount;
						vnConsumption = vnWaterUnit - vnPercentConsumption;
						vnWaterChargeNew = Double.parseDouble(MeterFunction.calNormalUsedUnitWater(vnSiteId, vaCustomerClass, vnConsumption).replace(",", ""));
					} else { // กรณีลด ค่าน้ำ
						vnWaterUnit = Double.parseDouble(vaDateAmount) * Double.parseDouble(vaWaterChargeLast);
						vnConsumption = vnWaterUnit;
						vnWaterChargeNew = (Double.parseDouble(MeterFunction.calNormalUsedUnitWater(vnSiteId, vaCustomerClass, vnConsumption).replace(",", ""))) - vnDiscount;
					}
				} else { // ถ้าไม่มีส่วนลดทหารผ่านศึก
					vnWaterUnit = (Double.parseDouble(vaDateAmount) * Double.parseDouble(vaWaterChargeLast));
					vnConsumption = vnWaterUnit;
					vnWaterChargeNew = Double.parseDouble(MeterFunction.calNormalUsedUnitWater(vnSiteId, vaCustomerClass, vnWaterUnit).replace(",", ""));
				}
			}
			catch(ParseException e){
				e.printStackTrace();
			}
		}
		voObject.put("consumption", (int) Math.round(vnConsumption));
		voObject.put("waterChargeNew", voFormatter.format(vnWaterChargeNew));
		voOut.print(voObject.toJSONString());
	}
	
	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		processRequest(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		processRequest(request, response);
	}

}
